#include "serverdialog.h"
#include "ui_serverdialog.h"

ServerDialog::ServerDialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::ServerDialog)
{
    ui->setupUi(this);
    //创建数据库
    createDB();
    //创建数据表
    createTable();
    //创建服务器
    if(tcpServer.listen(QHostAddress::Any,8080)==true){
        qDebug() << "创建服务器成功!";
        //开启定时器
        timer.start(3000);
    }
    else{
        qDebug() << "创建服务器失败";
    }
    //当有客户端向服务器发送连接请求,发送信号:newConnection
    connect(&tcpServer,SIGNAL(newConnection()),
            this,SLOT(onNewConnection()));
    //定时器到时发送信号:timeout
    connect(&timer,SIGNAL(timeout()),SLOT(onTimeout()));
}

ServerDialog::~ServerDialog()
{
    delete ui;
}
//创建数据库
void ServerDialog::createDB()
{
    //添加数据库驱动库
    db = QSqlDatabase::addDatabase("QSQLITE");
    //设置数据库名字(文件名)
    db.setDatabaseName("manager.db");
    //打开数据库
    if(db.open()==true){
        qDebug() << "打开数据库成功!";
    }
    else{
        qDebug() << "打开数据库失败!";
    }
}
//创建数据表
void ServerDialog::createTable()
{
    QSqlQuery query;
    QString str = QString("CREATE TABLE passenger ("
                          "username TEXT NOT NULL,"
                          "passwd TEXT NOT NULL,"
                          "money INT)");
    if(query.exec(str) == false){
        qDebug() << "创建数据表passenger失败!";
    }
    else{
        qDebug() << "创建数据表passenger成功!";
    }
    str = QString("CREATE TABLE driver ("
                          "username TEXT NOT NULL,"
                          "passwd TEXT NOT NULL,"
                          "plate TEXT NOT NULL)");//车牌号
    if(query.exec(str) == false){
        qDebug() << "创建数据表driver失败!";
    }
    else{
        qDebug() << "创建数据表driver成功!";
    }
    str = QString("CREATE TABLE order1 ("
                          "pname TEXT NOT NULL,"    //passengername
                          "dname TEXT NOT NULL,"    //drivername
                          "income REAL NOT NULL,"   //收入(对于系统/公司来说)
                          "pay REAL NOT NULL,"      //支出
                          "amount REAL NOT NULL,"   //实际抽成(赚的差价)
                          "time TEXT NOT NULL)");   //订单时间
    if(query.exec(str) == false){
        qDebug() << "创建数据表order失败!";
    }
    else{
        qDebug() << "创建数据表order成功!";
    }
}
//响应客户端连接请求的槽函数
void ServerDialog::onNewConnection()
{
    //获取和客户端通信的套接字
    QTcpSocket* tcpClient =  tcpServer.nextPendingConnection();
    //保存套接字到容器
    tcpClientList.append(tcpClient);
    //当客户端向服务器发送消息时,通信套接字发送信号:readyRead
    connect(tcpClient,SIGNAL(readyRead()),this,SLOT(onReadyRead()));
}
//接收客户端消息的槽函数
void ServerDialog::onReadyRead()
{
    //遍历容器哪个客户端给服务器发送了消息
    for(int i=0;i<tcpClientList.size();i++){
        //bytesAvailable:获取当前套接字等待读取消息字节数
        //返回0表示没有消息
        //返回>0,说明当前套接字有消息到来
        if(tcpClientList.at(i)->bytesAvailable()){
            //读取消息并保存
            QString buff = tcpClientList.at(i)->readAll();
            //qDebug() << buff;
            const QStringList buf = buff.split('+');
            switch(buf[0].toInt()){
                case 0:
                   pregister(buf);
                   break;
                case 1:
                   plogin(buf);
                   break;
                case 2:
                   ptake(buf);
                   break;
                case 3:
                   porder(buf);
                   break;
                case 4:
                   dregister(buf);
                   break;
                case 5:
                   dlogin(buf);
                   break;
                case 6:
                   dloc(buf);
                   break;
                case 7:
                   qDebug() << buf.at(1);
                   break;
                case 8:
                   qDebug() <<"司机到了乘客处";
                   dtob();
                   break;
                case 9:
                   qDebug() <<"司机到了目的地";
                   dtoe();
                   break;
                case 10:
                   dloc(buf);
                   break;
                default :
                   qDebug() << "消息格式错误!";
            } 
        }
    }
}
//发送消息给其它客户端
void ServerDialog::sendMessage(QString s)
{
    for(int i=0;i<tcpClientList.size();i++){
        tcpClientList.at(i)->write(s.toUtf8());
        //tcpClientList.at(i)->flush();
    }
}
//定时器到时后将执行的槽函数
void ServerDialog::onTimeout(void){
    //遍历检查容器中保存的客户端通信套接字是否已经断开链接,如果是则删除
    for(int i=0;i<tcpClientList.size();i++){
        if(tcpClientList.at(i)->state() ==
                QAbstractSocket::UnconnectedState){
            tcpClientList.removeAt(i);
            --i;
        }
    }
}
//乘客注册响应函数
void ServerDialog::pregister(QStringList b){
    QSqlQuery query;
    sql="insert into passenger(username,passwd) values('" + b[1]
            + "','" + b[2] +"')";
    qDebug() << "执行语句:"+sql;
    if(query.exec(sql) == false){
        sendMessage("0n");
        qDebug() << "注册失败！";
    }
    else{
        sendMessage("0y");
        qDebug() << "乘客"+b[1]+"注册成功！";
    }
}
//乘客登录响应函数
void ServerDialog::plogin(QStringList b){
    QSqlQuery query;
    sql="select * from passenger where username='" + b[1]
                + "' and passwd='" + b[2] +"'";
    qDebug() << "执行语句:"+sql;
    query.exec(sql);
    if(query.next() == false){
        sendMessage("1n");
        qDebug() << "登录失败！";
    }
    else{
        sendMessage("1y");
        qDebug() << "乘客"+b[1]+"登录成功！";
        pname=b[1];
    }
}
//乘客打车响应函数
void ServerDialog::ptake(QStringList b){
    qDebug() << "开始打车！";
    pbloc=b[1].toInt();
    peloc=b[2].toInt();
    sendMessage("b+"+b[1]);
}
//乘客预约打车响应函数
void ServerDialog::porder(QStringList b){
    int time=b[1].toInt();
    qDebug() << "倒计时：";
    while(time!=0){
        Sleep(1000);
        qDebug() <<time;
        time--;
    }
    b.removeAt(1);
    ptake(b);
}
//司机注册响应函数
void ServerDialog::dregister(QStringList b){
    QSqlQuery query;
    sql="insert into driver(username,passwd,plate) values('" + b[1]
            + "','" + b[2] +"','"+b[3]+"')";
    qDebug() << "执行语句:"+sql;
    if(query.exec(sql) == false){
        sendMessage("4n");
        qDebug() << "注册失败！";
    }
    else{
        sendMessage("4y");
        qDebug() << "司机"+b[1]+"注册成功！";
    }
}
//司机登录响应函数
void ServerDialog::dlogin(QStringList b){
    QSqlQuery query;
    sql="select * from driver where username='" + b[1]
                + "' and passwd='" + b[2] +"'";
    query.exec(sql);
    qDebug() << "执行语句:"+sql;
    if(query.next() == false){
        sendMessage("5n");
        qDebug() << "登录失败！";
    }
    else{
        sendMessage("5y");
        qDebug() << "司机"+b[1]+"登录成功！";
        dname=b[1];
    }
}
//司机发定位响应函数
void ServerDialog::dloc(QStringList b){
    //QString s="司机"+dname+"到了"+b.at(1);
    QString s="司机到了"+b.at(1);
    qDebug() <<s;
}
//司机到起始地响应函数
void ServerDialog::dtob(){
    QString s="e+"+QString("%1").arg(peloc);
    sendMessage(s);
}
//司机到目的地响应函数
void ServerDialog::dtoe(){
    total=abs(peloc-pbloc)*price;

    QSqlQuery query;
    QString sql = "select count(*) from order1 where pname="+dname;
    query.exec(sql);
    query.next();
    int pn=query.value(0).toInt();

    sql = "select count(*) from order1 where dname="+dname;
    query.exec(sql);
    query.next();
    int dn=query.value(0).toInt();

    if(pn/5==0){
        income=total-1;//每五次打车给乘客优惠一元
    }else{
        income=total;
    }

    if(dn<=5){
        pay=total*(1-cut_rate)+1;
    }else{
        pay=total*(1-cut_rate);
    }

    cut=income-pay;

    QString dataTime = QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");//获取当前时间
    qDebug() <<"时间:"+dataTime;
    sql = "insert into order1 values('"+pname+ "','" +dname+ "'," +QString("%1").arg(income)+ ","
            +QString("%1").arg(pay)+ "," +QString("%1").arg(cut)+ ",'" +dataTime+"')";
    if(query.exec(sql)==true){
        qDebug() <<"写入订单成功！";
    }else{
        qDebug() <<"写入订单失败！";
    }
    qDebug() <<"乘客支付"+QString("%1").arg(income)+"元";
    qDebug() <<"司机收款"+QString("%1").arg(pay)+"元";
    qDebug() <<"本单抽成"+QString("%1").arg(cut)+"元";
    sendMessage("7+支付"+QString("%1").arg(income)+"元+"+"收款"+QString("%1").arg(pay)+"元");
}
